/**----------------------------------------
 * @description 任务基类类
 * @author      lxc
 * @file        Task.ts
 * @Date        2022-05-22
 * @version     1.0.0
 * ----------------------------------------
 */

import { MsgProcess } from "../message/MsgProcess";
import { TaskClass, TaskState, TaskType } from "./TaskDefine";
import { TaskEnum } from "./TaskEnum";

export class Task extends MsgProcess {
    /**
     * 任务类型默认为顺序执行
     */
    protected taskType: TaskType = TaskType.Order;
    /**
     * 任务整体状态默认为等待
     */
    protected taskState: TaskState = TaskState.Wait;
    /**
     * 任务完成回调
     */
    protected complateCallBack: Function = null;
    /**
     * 任务存续时长，超过未完成则超时
     */
    protected remainTime: number = 3 * 60;
    /**
     * 当前主干任务完成状态
     */
    protected trunkFinish: boolean = false;
    /**
     * 子任务
     */
    protected childTasks: Task[] = [];
    /**
     * 子任务完成状态
     */
    protected childsFinish: boolean = false;

    trunkComplateState = false

    childComplateState = false

    constructor(taskEnum: TaskEnum, complateCallBack: Function) {
        super(taskEnum)
        this.complateCallBack = complateCallBack;
        this.init()
        this.printLog("task create")
    }
    /**
     * 任务初始化
     */
    init() {
        this.printLog("task init")
        this.initListeners()
    }
    /**
     * 添加子任务
     * @param taskEnum 
     * @param className 
     * @param complateCallBack 
     */
    addChildTask(taskEnum: TaskEnum, className: TaskClass, complateCallBack?: Function) {
        this.printLog("addChildTask", taskEnum)
        this.childTasks.push(new className(taskEnum, complateCallBack))
    }
    /**
     * 
     * @param dt 
     * @returns 返回已完成的任务
     */
    updateState(dt): Task {
        this.countTime(dt);
        return
    }

    taskExcute(dt) {
        this.countTime(dt)
        if (this.precondition()) {
            this.printLog("")
        }
    }

    taskExcuting() {
        this.printLog("taskExcuting")
        this.trunkComplate()
    }

    trunkComplate() {
        this.printLog("trunkComplate")
        this.trunkComplateState = true;
        this.taskComplate()
    }

    taskComplate() {
        this.printLog("taskComplate")
        if (this.taskState != TaskState.Complate) {
            if (this.trunkComplateState && this.childComplateState) {
                this.printLog("task total Complate")
                this.complateCallBack && this.complateCallBack()
                this.taskState = TaskState.Complate
            }
        }
    }

    excuteChildTask(dt) {
        this.printLog("excuteChildTask")
        let complate = true;
        this.childTasks.forEach((task) => {
            if(task.taskState == TaskState.Wait){
                task.taskExcute(dt);
                complate = false;
            }else if (task.taskState == TaskState.Excute){
                task.judgeTaskComplate(0);
                complate = false;
            }
        })
        complate && this.childTaskComplate()
    }

    judgeTaskComplate(dt){
        if(this.childTasks.length <=0){
            this.childTaskComplate()
        } else {
            if(dt > 0){
                this.excuteChildTask(dt)
            }
        }
        this.taskExcuting()
        this.countTime(dt)
    }

    childTaskComplate(){
        this.printLog("childTaskComplate")
        this.childComplateState = true;
        this.taskComplate()
    }

    countTime(dt) {
        this.remainTime -= dt;
        if (this.remainTime <= 0) {
            this.printError("TaskTimeOut")
            this.taskState = TaskState.TimeOut
        }
    }
    /**
     * 设置任务持续时间
     * @param time 
     */
    setDruration(time: number) {
        this.printLog("task druration", time)
        this.remainTime = time;
    }

    protected precondition() {
        this.printLog("precondition")
        return true;
    }

    getState(){
        return this.taskState;
    }

    dumpTask() {
        this.printLog("dumpTask taskState", this.taskState)
        this.childTasks.forEach((task) => {
            task.dumpTask();
        })
    }
}